package com.kfm.proxy;

import com.kfm.dao.AccountDao;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.util.HashMap;
import java.util.Map;

public class DynamicProxy {

    public static void main(String[] args) {

        /*
            CGLib 代理是基于 类的代理模式
             动态创建一个类继承被代理的类
         */
        Kun kun = new Kun();
        Kun o = (Kun) Enhancer.create(Kun.class, new MethodInterceptor() {

            @Override
            public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
                System.out.println("intercept");
                return null;
            }
        });

        o.sing(1000.0);
    }


    public static void jdkProxy(){
        Kun kun = new Kun();

        /*
            JDK 动态代理
            Proxy.newProxyInstance 动态创建一个代理对象
                args：
                 classLoader  类加载器
                 interfaces   代理类要实现的接口
                 handler      代理对象的处理方法

                 class XX implements Actor{}
         */
        Actor proxyInstance = (Actor) Proxy.newProxyInstance(Kun.class.getClassLoader(),
                kun.getClass().getInterfaces(),
                new InvocationHandler() {
                    /**
                     * 代理对象在执行方法时，实际会执行此方法
                     * 拦截了方法的执行
                     * @param proxy 代理对象的引用。不一定每次都用得到
                     * @param method 当前执行的方法对象
                     * @param args 执行方法所需的参数
                     * @return 当前执行方法的返回值
                     * @throws Throwable
                     *
                     */
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("invoke");
                        System.out.println("收钱不办事");
//                        if ("sing".equals(method.getName())){
//                            kun.sing((Double) args[0]);
//                        }
                        return null;
                    }
                }
        );

        // 代理对象来执行操作
        proxyInstance.sing(1000.0);

        //
        Map<String, Object> configuration = new HashMap<>();

        AccountDao dao = (AccountDao) Proxy.newProxyInstance(StaticProxy.class.getClassLoader(),
                new Class[]{AccountDao.class},
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        String className = method.getDeclaringClass().getName();
                        String methodName = method.getName();
                        configuration.get(className + "." + methodName);

                        Connection conn = null;
                        return null;
                    }
                }
        );

        dao.insert(null);
    }
}
